package com.googlecode.mailnet.emf.netmodel.diagram.part;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.runtime.notation.View;

import com.googlecode.mailnet.emf.netmodel.LinkModel;
import com.googlecode.mailnet.emf.netmodel.NetmodelPackage;
import com.googlecode.mailnet.emf.netmodel.NetworkConfigurationModel;
import com.googlecode.mailnet.emf.netmodel.NodeModel;
import com.googlecode.mailnet.emf.netmodel.diagram.edit.parts.LinkModelEditPart;
import com.googlecode.mailnet.emf.netmodel.diagram.edit.parts.NetworkConfigurationModelEditPart;
import com.googlecode.mailnet.emf.netmodel.diagram.edit.parts.NodeModelEditPart;
import com.googlecode.mailnet.emf.netmodel.diagram.providers.NetmodelElementTypes;

/**
 * @generated
 */
public class NetmodelDiagramUpdater {

	/**
	 * @generated
	 */
	public static List getSemanticChildren(View view) {
		switch (NetmodelVisualIDRegistry.getVisualID(view)) {
		case NetworkConfigurationModelEditPart.VISUAL_ID:
			return getNetworkConfigurationModel_79SemanticChildren(view);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getNetworkConfigurationModel_79SemanticChildren(View view) {
		if (!view.isSetElement()) {
			return Collections.EMPTY_LIST;
		}
		NetworkConfigurationModel modelElement = (NetworkConfigurationModel) view
				.getElement();
		List result = new LinkedList();
		for (Iterator it = modelElement.getNodes().iterator(); it.hasNext();) {
			NodeModel childElement = (NodeModel) it.next();
			int visualID = NetmodelVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == NodeModelEditPart.VISUAL_ID) {
				result.add(new NetmodelNodeDescriptor(childElement, visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List getContainedLinks(View view) {
		switch (NetmodelVisualIDRegistry.getVisualID(view)) {
		case NetworkConfigurationModelEditPart.VISUAL_ID:
			return getNetworkConfigurationModel_79ContainedLinks(view);
		case NodeModelEditPart.VISUAL_ID:
			return getNodeModel_1001ContainedLinks(view);
		case LinkModelEditPart.VISUAL_ID:
			return getLinkModel_3001ContainedLinks(view);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getIncomingLinks(View view) {
		switch (NetmodelVisualIDRegistry.getVisualID(view)) {
		case NodeModelEditPart.VISUAL_ID:
			return getNodeModel_1001IncomingLinks(view);
		case LinkModelEditPart.VISUAL_ID:
			return getLinkModel_3001IncomingLinks(view);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getOutgoingLinks(View view) {
		switch (NetmodelVisualIDRegistry.getVisualID(view)) {
		case NodeModelEditPart.VISUAL_ID:
			return getNodeModel_1001OutgoingLinks(view);
		case LinkModelEditPart.VISUAL_ID:
			return getLinkModel_3001OutgoingLinks(view);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getNetworkConfigurationModel_79ContainedLinks(View view) {
		NetworkConfigurationModel modelElement = (NetworkConfigurationModel) view
				.getElement();
		List result = new LinkedList();
		result
				.addAll(getContainedTypeModelFacetLinks_LinkModel_3001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List getNodeModel_1001ContainedLinks(View view) {
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getLinkModel_3001ContainedLinks(View view) {
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getNodeModel_1001IncomingLinks(View view) {
		NodeModel modelElement = (NodeModel) view.getElement();
		Map crossReferences = EcoreUtil.CrossReferencer.find(view.eResource()
				.getResourceSet().getResources());
		List result = new LinkedList();
		result.addAll(getIncomingTypeModelFacetLinks_LinkModel_3001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List getLinkModel_3001IncomingLinks(View view) {
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public static List getNodeModel_1001OutgoingLinks(View view) {
		NodeModel modelElement = (NodeModel) view.getElement();
		List result = new LinkedList();
		result
				.addAll(getOutgoingTypeModelFacetLinks_LinkModel_3001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List getLinkModel_3001OutgoingLinks(View view) {
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	private static Collection getContainedTypeModelFacetLinks_LinkModel_3001(
			NetworkConfigurationModel container) {
		Collection result = new LinkedList();
		for (Iterator links = container.getLinks().iterator(); links.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof LinkModel) {
				continue;
			}
			LinkModel link = (LinkModel) linkObject;
			if (LinkModelEditPart.VISUAL_ID != NetmodelVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			NodeModel dst = link.getDestination();
			NodeModel src = link.getSource();
			result.add(new NetmodelLinkDescriptor(src, dst, link,
					NetmodelElementTypes.LinkModel_3001,
					LinkModelEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection getIncomingTypeModelFacetLinks_LinkModel_3001(
			NodeModel target, Map crossReferences) {
		Collection result = new LinkedList();
		Collection settings = (Collection) crossReferences.get(target);
		for (Iterator it = settings.iterator(); it.hasNext();) {
			EStructuralFeature.Setting setting = (EStructuralFeature.Setting) it
					.next();
			if (setting.getEStructuralFeature() != NetmodelPackage.eINSTANCE
					.getLinkModel_Destination()
					|| false == setting.getEObject() instanceof LinkModel) {
				continue;
			}
			LinkModel link = (LinkModel) setting.getEObject();
			if (LinkModelEditPart.VISUAL_ID != NetmodelVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			NodeModel src = link.getSource();
			result.add(new NetmodelLinkDescriptor(src, target, link,
					NetmodelElementTypes.LinkModel_3001,
					LinkModelEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection getOutgoingTypeModelFacetLinks_LinkModel_3001(
			NodeModel source) {
		NetworkConfigurationModel container = null;
		// Find container element for the link.
		// Climb up by containment hierarchy starting from the source
		// and return the first element that is instance of the container class.
		for (EObject element = source; element != null && container == null; element = element
				.eContainer()) {
			if (element instanceof NetworkConfigurationModel) {
				container = (NetworkConfigurationModel) element;
			}
		}
		if (container == null) {
			return Collections.EMPTY_LIST;
		}
		Collection result = new LinkedList();
		for (Iterator links = container.getLinks().iterator(); links.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof LinkModel) {
				continue;
			}
			LinkModel link = (LinkModel) linkObject;
			if (LinkModelEditPart.VISUAL_ID != NetmodelVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			NodeModel dst = link.getDestination();
			NodeModel src = link.getSource();
			if (src != source) {
				continue;
			}
			result.add(new NetmodelLinkDescriptor(src, dst, link,
					NetmodelElementTypes.LinkModel_3001,
					LinkModelEditPart.VISUAL_ID));
		}
		return result;
	}

}
